package com.ibm.corebanking.idmf.dubbo.client.annotation;

import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.ibm.corebanking.idmf.dubbo.client.MultiServiceCodeResolver;

/**
 * 对象工厂，用于生成Dubbo客户端，配套处理单元化问题
 * 
 * @author WeiZhou
 *
 * @param <T> 接口类型
 */
public class DubboReferenceBeanFactory<T> implements FactoryBean<T>, ApplicationContextAware {
	private Class<T> interfaceClass;
	private Class<MultiServiceCodeResolver> serviceCodeResolverCls;
	@Autowired
	ApplicationConfig appConf;
	@Autowired
	RegistryConfig regConf;

	public DubboReferenceBeanFactory(Class<T> interfaceClass, Class<MultiServiceCodeResolver> serviceCodeResolver) {
		super();
		this.interfaceClass = interfaceClass;
		this.serviceCodeResolverCls = serviceCodeResolver;
	}

	@Override
	public T getObject() throws Exception {

		StringBuilder group = new StringBuilder();
		int i = (int) (Math.random() * 10) % 2 + 1;
		if (name.contains("$CLUSTER")) {
			// FIXME: get IDC id
			group.append("DC1");
		}
		if (name.contains("$DUS_ID")) {
			// FIXME: get DUS id
			if (group.length() > 1) {
				group.append("-").append("DUS").append(i);
			} else {
				group.append("DUS").append(i);
			}
		}
		if (serviceCodeResolverCls != null) {
			MultiServiceCodeResolver resolver = applicationContext.getBean(serviceCodeResolverCls);
			String svrCode = resolver.resolveServiceCode();
			if (group.length() > 1) {
				group.append("-").append(svrCode);
			} else {
				group.append(svrCode);
			}
		}
		System.out.println("group = " + group + " i = " + i);

		// TODO 处理Version,Tag
		ReferenceConfig<T> referenceConfig = new ReferenceConfig<>();

		referenceConfig.setRegistry(regConf);
		referenceConfig.setApplication(appConf);
		if (group.length() > 1) {
			referenceConfig.setGroup(group.toString());
		}
		referenceConfig.setInterface(interfaceClass);
		ReferenceConfigCache cache = ReferenceConfigCache.getCache();
		return cache.get(referenceConfig);
//		return referenceConfig.get();

	}

	@Override
	public Class<?> getObjectType() {
		return interfaceClass;
	}

	private String url;
	private String path;
	private boolean primary;
	private String name;

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public boolean isPrimary() {
		return primary;
	}

	public void setPrimary(boolean primary) {
		this.primary = primary;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;

	}

}
